package com.wulin.wucut.utils;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.FileTypeUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.file.FileCopier;
import cn.hutool.core.io.file.PathUtil;
import cn.hutool.core.lang.func.Func;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSONObject;
import com.wulin.wucut.common.JianYinConstant;
import com.wulin.wucut.common.SuffixConstant;
import com.wulin.wucut.domain.entity.draft.meta.info.DraftMaterials;
import com.wulin.wucut.domain.entity.draft.meta.info.DraftMaterialsValue;
import com.wulin.wucut.properties.JianYinDraftProperties;

import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class JianYinUtil {
    public static final String PATH_SPLIT = "/";

    private static final JianYinDraftProperties properties = SpringUtil.getBean(JianYinDraftProperties.class);
    public static String getDraftMetaInfoPath(String directory, String draftName) {
        return directory + PATH_SPLIT + draftName + PATH_SPLIT + JianYinConstant.DRAFT_META_INFO + SuffixConstant.JSON;
    }
    public static String getDraftContentPath(String directory, String draftName) {
        return directory + PATH_SPLIT + draftName + PATH_SPLIT + JianYinConstant.DRAFT_CONTENT + SuffixConstant.JSON;
    }
    public static String getDraftMetaInfoPath(){
        return getDraftMetaInfoPath(properties.getDirectory(), properties.getName());
    }
    public static String getDraftContentPath() {
        return getDraftContentPath(properties.getDirectory(), properties.getName());
    }
    public static String getDraftContentPath(String draftName) {
        return getDraftContentPath(properties.getDirectory(), draftName);
    }
    public static JSONObject getDraftMetaInfo() {
        String draftMetaInfoPath = getDraftMetaInfoPath();
        String jsonStr = FileUtil.readUtf8String(draftMetaInfoPath);
        return JSONObject.parseObject(jsonStr);
    }

    public static DraftMaterials getDraftMaterials() {
        String draftMetaInfoPath = getDraftMetaInfoPath();
        String jsonStr = FileUtil.readUtf8String(draftMetaInfoPath);
        return JSONObject.parseObject(jsonStr, DraftMaterials.class);
    }
    public static DraftMaterialsValue getDraftMaterialsValue(Integer type) {
        for (DraftMaterialsValue draftMaterialsValue : getDraftMaterials().getValue()) {
            if (JianYinConstant.DRAFT_MATERIALS_TYPE.equals(type)) {
                return draftMaterialsValue;
            }
        }
        return null;
    }
    
    public static JSONObject getDraftContent() {
        String draftContentPath = getDraftContentPath();
        String read = FileUtil.readUtf8String(draftContentPath);
        return JSONObject.parseObject(read);
    }
    public static JSONObject getDraftContent(String draftName) {
        String draftContentPath = getDraftContentPath(properties.getDirectory(), draftName);
        String read = FileUtil.readUtf8String(draftContentPath);
        return JSONObject.parseObject(read);
    }
    public static void write(String content) {
        FileUtil.writeUtf8String(content ,getDraftMetaInfoPath());
    }
    
    
    public static String getPath(String... directory) {
        StringBuilder path = new StringBuilder();
        for (int i = 0; i < directory.length; i++) {
            if (i < directory.length - 1) {
                path.append(directory[i]).append(PATH_SPLIT);
            }else {
                path.append(directory[i]);
            }
        }
        return path.toString();
    }
    
    public static String getId() {
        return UUID.randomUUID().toString();
    }
    
    
    public static Long getRandomSplit() {
        Integer splitMin = properties.getSplitMin();
        Integer splitMax = properties.getSplitMax();
        int i = RandomUtil.randomInt(splitMin, splitMax);
        return i * 1000 * 1000L;
    }

    public static Double getRandomSpeed() {
        Double speedMin = properties.getSpeedMin();
        Double speedMax = properties.getSpeedMax();
        return speedMax.equals(speedMin)?speedMin: RandomUtil.randomDouble(speedMin, speedMax, 1, RoundingMode.HALF_UP);
    }
    
    public static Integer getRandomRange() {
        Integer videoMin = properties.getVideoMin();
        Integer videoMax = properties.getVideoMax();
        if (Objects.equals(videoMax, videoMin)) {
            return videoMin;
        }
        return RandomUtil.randomInt(videoMin, videoMax);
    }
    
    
    
    public static Integer getRandomBlur() {
        Integer blurMin = properties.getBlurMin();
        Integer blurMax = properties.getBlurMax();
        return blurMin.equals(blurMax) ? blurMax : RandomUtil.randomInt(blurMin, blurMax);
    }

    
    public static List<String> getAllFiles() {
        String file = properties.getFile();
        
        return FileUtil.listFileNames(file)
                .stream()
                .map(item ->file +"/"+ item)
                .collect(Collectors.toList());
    }
    
    
    public static List<String> copyDraftFile() {
        String directory = properties.getDirectory();
        String name = properties.getName();
        String draftDirectory = directory + "/" + name;
        Integer num = properties.getNum();
        List<String> draftFilePath = new ArrayList<>();
        List<String> fileNames = Arrays.stream(FileUtil.ls(directory)).map(file -> file.getName()).collect(Collectors.toList());
        int index = 0;
        int i = 0;
        while (i < num) {
            String copyFileName = name+"_悟灵剪辑_" + index;
            String copyDraftPath = directory +"/"+copyFileName ;
            if (fileNames.contains(copyFileName)) {
                index++;
                continue;
            }
            FileCopier.create(draftDirectory, copyDraftPath).setCopyContentIfDir(true).copy();
            draftFilePath.add(copyFileName);      
            i++;
            index++;
        }
      
        return draftFilePath;
    }

    

    /**
     * 字幕合并
     * @param srtPathList srt集合
     * @param srtMergeName srt合并后的名字
     */
    public static void srtMerge(List<String> srtPathList, String srtMergeName) throws IOException {
        if (CollUtil.isEmpty(srtPathList) && srtPathList.size() <= 1) {
            return;
        }
        DateTimeFormatter pattern = DateTimeFormatter.ofPattern("HH:mm:ss,SSS");
        List<List<String>> newSrtContent = new ArrayList<>();
        for (int i = 0; i < srtPathList.size(); i++) {
            //当前srt
            String srt0Path = srtPathList.get(i);
            List<String> srtContent = FileUtil.readUtf8Lines(new File(srt0Path), (Predicate<String>) StrUtil::isNotBlank);
            //第一个srt直接放入，无需处理
            if (CollUtil.isNotEmpty(newSrtContent)) {
                //前一个srt
                List<String> preSrt = newSrtContent.get(newSrtContent.size() - 1);
                Integer preSrtLine = Integer.valueOf(preSrt.get(preSrt.size() - 3));
                List<String> preSrtTime = srtList(preSrt.get(preSrt.size() - 2));
                String preSrtLastTime = preSrtTime.get(1);
                LocalTime preLastTime = LocalTime.parse(preSrtLastTime, pattern);
                preLastTime.plusNanos(300);
                if (i != 0) {
                    for (int i1 = 0; i1 < srtContent.size();i1++) {
                        Integer srtLine = Convert.toInt((srtContent.get(i1)));
                        //行数加上前一个srt的最后行数
                        srtContent.set(i1, String.valueOf(srtLine + preSrtLine));
                        //时间加上前一个srt的结束时间
                        String srtText = srtContent.get(++i1);
                        List<String> strings = srtList(srtText);
                        String srtStartTime = strings.get(0);
                        String srtEndTime = strings.get(1);
                        
                        LocalTime startTime = LocalTime.parse(srtStartTime, pattern);
                        LocalTime endTime = LocalTime.parse(srtEndTime, pattern);
                        LocalTime newStartTime =   plus(startTime,preLastTime);
                        LocalTime newEndTime =   plus(endTime,preLastTime);
                        //合并后的字幕
                        String newSrtTime = newStartTime.format(pattern) + " --> " + newEndTime.format(pattern);
                        srtContent.set(i1, newSrtTime);
                        i1++;
                    }
                }
            }
            newSrtContent.add(srtContent);
        }
        BufferedWriter writer = FileUtil.getWriter(srtMergeName, StandardCharsets.UTF_8, false);
        int j = 0;
        for (List<String> strings : newSrtContent) {
            for (int i = 0; i < strings.size(); i++) {
                writer.write(strings.get(i));
                writer.write("\r\n");
                j++;
                if (j == 3) {
                    writer.write("\r\n");
                    j = 0;
                }
            }
           
        }
        writer.flush();
        
    }

    public static LocalTime plus(LocalTime time, LocalTime plusTime) {
        return time.plusHours(plusTime.getHour())
                .plusMinutes(plusTime.getMinute())
                .plusSeconds(plusTime.getSecond())
                .plusNanos(plusTime.getNano());
        
    }


    public static String timeToStr(String time) {
        String defaultTimeTemplate = "{8}{7}:{6}{5}:{4}{3},{2}{1}{0}";
        String timeReverse = StrUtil.reverse(time) ;
        HashMap<Integer, Object> map = new HashMap<>();
        for (int i = 8; i >= 0; i--) {
            map.put(i, i>=timeReverse.length()? '0':String.valueOf(timeReverse.charAt(i)));
        }
        return StrUtil.format(defaultTimeTemplate, map);
    }

   
    
    public static List<String> srtList(String fullSrtTime) {
        List<String> fullStr = StrUtil.split(fullSrtTime, " --> ");
        return fullStr;
    }
    public static Integer srtStringTimeToInt(String srtTime) {
        List<String> split = StrUtil.split(srtTime, ":");
        String lastText = split.get(split.size() - 1);
        List<String> lastSplit = StrUtil.split(lastText, ",");
        split.remove(split.size() - 1);
        split.addAll(lastSplit);
        String join = StrUtil.join("", split);
        return Convert.toInt(join);
    }
    
    public static Integer getDraftNum() {
        return properties.getNum();
    }
    
    public static double getRandomXLocation() {
        Integer locationXMax = properties.getLocationXMax();
        Integer locationXMin = properties.getLocationXMin();
        return  (Objects.equals(locationXMin, locationXMax) ? locationXMin : RandomUtil.randomInt(locationXMin, locationXMax, true, true)) * 0.000925925925925926;

    }
    public static double getRandomYLocation() {
        Integer locationYMax = properties.getLocationYMax();
        Integer locationYMin = properties.getLocationYMin();
        return  (Objects.equals(locationYMin, locationYMax) ? locationYMin : RandomUtil.randomInt(locationYMin, locationYMax, true, true)) * 0.0005208333333333333;
    }
    public static double getRandomScale() {
        Integer scaleMin = properties.getScaleMin();
        Integer scaleMax = properties.getScaleMax();
        return (Objects.equals(scaleMin,scaleMax)   ? scaleMax : RandomUtil.randomInt(scaleMin, scaleMax,true,true));
    }
}
